// backend/src/services/device/websocket.js
const WebSocket = require('ws');
const jwt = require('jsonwebtoken');
const robotProxy = require('../robot/RobotProxy');
const logger = require('../../utils/logger');
const config = require('../../config/default');

class WebSocketServer {
    constructor(config) {
        this.config = config;
        this.initialize();
    }

    initialize() {
        this.wss = new WebSocket.Server({
            port: this.config.ws.port,
            host: this.config.ws.host
        });

        this.setupEventHandlers();
        logger.info(`WebSocket server starting on ${this.config.ws.host}:${this.config.ws.port}`);
    }

    setupEventHandlers() {
        this.wss.on('connection', async (ws, req) => {
            let authenticated = false;
            let userData = null;
            let currentRobotId = null;

            // 添加心跳检测
            let pingTimeout;

            const heartbeat = () => {
                clearTimeout(pingTimeout);
                pingTimeout = setTimeout(() => {
                    logger.warn('WebSocket connection timed out');
                    ws.terminate();
                }, 30000); // 30秒超时
            };

            ws.on('pong', heartbeat);
            heartbeat();

            ws.on('message', async (message) => {
                try {
                    const data = JSON.parse(message);

                    // 处理认证
                    if (data.type === 'auth') {
                        const authResult = await this.handleAuth(ws, data.token);
                        authenticated = authResult.authenticated;
                        userData = authResult.userData;
                        return;
                    }

                    if (!authenticated) {
                        ws.send(JSON.stringify({
                            type: 'error',
                            message: 'Not authenticated'
                        }));
                        return;
                    }

                    // 处理机器人连接
                    if (data.type === 'connect_robot') {
                        await this.handleRobotConnection(ws, data, userData);
                        currentRobotId = data.deviceId;
                        return;
                    }

                    // 处理命令
                    if (data.type === 'robot_command') {
                        await this.handleRobotCommand(ws, currentRobotId, data);
                        return;
                    }

                } catch (error) {
                    logger.error('WebSocket message error:', error);
                    ws.send(JSON.stringify({
                        type: 'error',
                        message: 'Message processing error'
                    }));
                }
            });

            ws.on('close', () => {
                if (currentRobotId) {
                    // 清理订阅关系
                }
                logger.info(`Client disconnected: ${userData?.username || 'unknown'}`);
            });
        });
    }

    startHeartbeat() {
        setInterval(() => {
            this.wss.clients.forEach(ws => {
                if (ws.isAlive === false) {
                    logger.warn('Terminating inactive connection');
                    return ws.terminate();
                }
                ws.isAlive = false;
                ws.ping();
            });
        }, 10000); // 每10秒检查一次
    }

    async handleAuth(ws, token) {
        try {
            logger.info('Attempting to authenticate token');
            if (!token) {
                logger.warn('No token provided');
                ws.send(JSON.stringify({
                    type: 'auth_error',
                    message: 'Token is required'
                }));
                return { authenticated: false, userData: null };
            }

            const decoded = jwt.verify(token, config.jwt.secret);
            logger.info(`User authenticated successfully: ${decoded.username}`);
            ws.send(JSON.stringify({
                type: 'auth_success',
                user: decoded
            }));
            return { authenticated: true, userData: decoded };
        } catch (error) {
            logger.error('Token verification failed:', error);
            ws.send(JSON.stringify({
                type: 'auth_error',
                message: 'Invalid token'
            }));
            return { authenticated: false, userData: null };
        }
    }

    async handleRobotConnection(ws, data, userData) {
        try {
            const success = await robotProxy.connectToRobot(data.deviceId, data.robotAddress);
            if (success) {
                robotProxy.subscribeClient(data.deviceId, ws);
                ws.send(JSON.stringify({
                    type: 'robot_connection_success',
                    deviceId: data.deviceId
                }));
            } else {
                ws.send(JSON.stringify({
                    type: 'robot_connection_error',
                    message: 'Failed to connect to robot'
                }));
            }
        } catch (error) {
            logger.error('Error connecting to robot:', error);
            ws.send(JSON.stringify({
                type: 'error',
                message: 'Robot connection failed'
            }));
        }
    }

    async handleRobotCommand(ws, robotId, data) {
        try {
            await robotProxy.sendCommand(robotId, data.command);
        } catch (error) {
            logger.error('Error sending command to robot:', error);
            ws.send(JSON.stringify({
                type: 'error',
                message: 'Failed to send command to robot'
            }));
        }
    }
}

module.exports = WebSocketServer;
